#ifndef __MOD_CAN_H__
#define __MOD_CAN_H__

#include "typedef.h"

enum CanKeepliveState{
	E_KEEPLIVE_NORMAL = 0, /*心跳接收正常*/
	E_KEEPLIVE_OVERTIME = 1 /*心跳接收超时*/
};

enum CanCmdType
{
    /*命令帧*/
    CMD_CHARGE_START = 256  /*充电启动帧*/
   ,CMD_CHARGE_START_ACK = 512  /*充电启动帧应答*/
   ,CMD_CHARGE_STOP = 768  /*充电停止帧*/
   ,CMD_CHARGE_STOP_ACK = 1024  /*充电停止帧应答*/
   ,CMD_TIME_SYNC = 1280  /*对时帧*/
   ,CMD_TIME_SYNC_ACK = 1536  /*对时帧应答*/
   ,CMD_VER_CHECK = 1792  /*版本校验帧*/
   ,CMD_VER_CHECK_ACK = 2048  /*版本校验帧应答*/
   ,CMD_CHARGE_PARA = 2304  /*下发充电参数信息帧*/
   ,CMD_CHARGE_PARA_ACK = 2560  /*下发充电参数信息帧应答*/
   ,CMD_SET_SERVER = 2816  /*充电服务启停控制帧*/
   ,CMD_SET_SERVE_ACK = 3072  /*充电服务启停控制应答帧*/
   ,CMD_SET_LOCK = 3328  /*电子锁控制帧*/
   ,CMD_SET_LOCK_ACK = 3584  /*电子锁控制应答帧*/
   ,CMD_SET_POWER = 3840  /*功率调节控制帧*/
   ,CMD_SET_POWER_ACK = 4096  /*功率调节控制应答帧*/
   ,CMD_REQ_CONFIG = 24576  /*充电桩配置信息查询帧*/
   ,CMD_REQ_CONFIG_ACK = 24832  /*充电桩配置信息查询应答帧*/
    
    /*状态帧*/
   ,CHARGE_START_FINSH = 4352  /*充电启动完成帧*/
   ,CHARGE_START_FINSH_ACK = 4608  /*充电启动完成应答帧*/
   ,CHARGE_STOP_FINSH = 4864  /*充电停止完成帧*/
   ,CHARGE_STOP_FINSH_ACK = 5120  /*充电停止完成应答帧*/
    
    /*直流数据帧*/
   ,YC_DC_8192 = 8192  /*遥测帧 充电控制器-计费控制单元0x20*/
   ,YC_DC_8448 = 8448  /*遥测帧 计费单元到充电控制器0x21*/
   ,YX_DC_8704 = 8704  /*遥信帧 充电控制器到计费单元0x22*/
   ,YX_DC_8960 = 8960  /*遥信帧 充电控制器到计费单元0x23*/
    
    /*交流数据帧 暂时不用*/
   ,YC_12288 = 12288 /*遥测帧 充电控制器-计费控制单元*/
   ,YC_12544 = 12544 /*遥测帧 计费单元到充电控制器*/
   ,YX_AC_12800 = 12800 /*遥信帧 充电控制器到计费单元*/
   ,YX_AC_13056= 13056 /*遥信帧 计费单元到充电控制器*/
    
    /*心跳帧*/
   ,KEEP_LIVE_COST = 16384 /*计费控制单元心跳帧*/
   ,KEEP_LIVE_CONTROL = 16640 /*充电控制器心跳帧*/
    
    /*错误帧*/
   ,ERROR_COST = 20736 /*计费控制单元错误状态帧*/
   ,ERROR_CONTROL = 20992 /*充电控制器错误状态帧*/
};

#pragma pack(1)  //为了直接与协议对应

struct CanKeepLiveAck{
    uint8_t gunnum;
    uint8_t cnt;
    uint8_t state;
    uint8_t charge_state;
};

/*启动充电应答*/
struct CanChargeStartAck {
	uint8_t gunnum;
	uint8_t control;
	uint8_t flag;
	uint8_t failreason;
};

/*停止充电应答*/
struct CanChargeEndAck {
	uint8_t gunnum;	
	uint8_t flag;
};

/*对时帧应答*/
struct CanTimeSyncAck {
	uint8_t gunnum;
	uint8_t timebuf[7];
};

/*版本校验应答*/
struct CanVerCheckAck {
	uint8_t gunnum;
	uint16_t ver;
};

/*下发充电参数应答应答*/
struct CanSetConfigAck {
	uint8_t gunnum;
	uint8_t flag;
	uint8_t failreason;
};

/*充电服务启停应答*/
struct CanSetServerAck {
	uint8_t gunnum;
	uint8_t opera;
	uint8_t flag;
	uint8_t failreason;
};

/*电磁锁控制应答*/
struct CanSetLockAck {
	uint8_t gunnum;
	uint8_t lockno;
	uint8_t opera;
	uint8_t flag;
	uint8_t failreason;
};

/*功率调节应答*/
struct CanSetPowerAck {
	uint8_t gunnum;
	uint8_t type;
	uint8_t value;
	uint8_t flag;
	uint8_t failreason;
};

/*配置信息查询应答*/
struct CanReqConfigAck {
	uint8_t  gunnum;
	uint32_t factroyno;
	uint16_t devtype;
	uint8_t hardwarever[2];
	uint8_t softwarever[3];
	uint8_t softwaredate[4];
	uint8_t bmsconnver;
	uint16_t devmaxopvol;
	uint16_t devminopvol;
	uint16_t devmaxopcurr;
	uint16_t devminopcurr;
};

/*启动充电完成帧*/
struct CanStartChargeFinish {
	uint8_t gunnum;
	uint8_t control;
	uint8_t flag;
	uint8_t failreason;
	uint8_t devbmsconnprover[3];
	uint8_t bmsdevconnprover[3];
	uint8_t devbmshandresult;
	uint8_t batttype;
	uint8_t allowmaxtemp;
	uint16_t bmsmaxvol;
	uint16_t singlemaxvol;
	uint16_t maxcurr;
	uint16_t batttotalvol;
	uint16_t battvolnow;
	uint16_t batttotalah;
	uint16_t batttotalkwh;
	uint16_t totalsocstate;
	uint16_t devmaxopvol;
	uint16_t devminopvol;
	uint16_t devmaxopcurr;
	uint16_t devminopcurr;
	uint8_t vin[17];
};


/*停止充电完成帧*/
struct CanStopChargeFinish {
	uint8_t gunnum;
    uint8_t stopreason;
	uint8_t flag;
    
	uint8_t bmsstop_soc:2; /*soc到达目标值*/
    uint8_t bmsstop_total_vol:2; /*电压到达设定值*/
    uint8_t bmsstop_single_vol:2; /*达到单体电压设定值*/
    uint8_t bmsstop_bms_stop:2;   /*充电机主动终止*/
    
	uint16_t bmsfail_isolate:2;  /*绝缘故障*/
	uint16_t bmsfail_linker_over_temp:2; /*输出连接器过温*/
	uint16_t bmsfail_bms_over_temp:2; /*bms元件，连接器过温*/
	uint16_t bmsfail_linker_fail:2; /*充电连接器故障*/
    
	uint16_t bmsfail_battery_over_temp:2; /*电池组温度过温*/
	uint16_t bmsfail_relay_fail:2; /*高压继电器故障*/
	uint16_t bmsfail_check_point:2; /*检测点2电压故障*/
	uint16_t bmsfail_other:2; /*其他故障*/
    
	uint8_t bmserr_over_currt:2; /*电流过大*/
	uint8_t bmserr_vol_err:2; /*电压异常*/
	uint8_t bmserr_res:4;    /*占位，未使用*/
    
	uint8_t stopsocstate;
	uint16_t battsingleminvol;
	uint16_t battsinglemaxvol;
	uint8_t battmintemp;
	uint8_t battmaxtemp;
    
	uint8_t recvspn25600x00over:2;
	uint8_t recvspn25600xaaover:2;
	uint8_t recvtimesyncover:2;
	uint8_t recvdevparpreover:2;
    
	uint16_t recvdevchastateover:2;
	uint16_t recvdevstopchaover:2;
	uint16_t recvdevcalover:2;
	uint16_t bmsothererror:6;
	uint16_t recvbmsover:2;
	uint16_t recvbattchaparaover:2;
    
	uint16_t recvbmsfinishchaparpreover:2;
	uint16_t recvbattchastateover:2;
	uint16_t recvbattchareqover:2;
	uint16_t recvbmsstopchaover:2;
	uint16_t recvbmschacalover:2;
	uint16_t devothererror:6;
    
};

/*8192遥测帧*/
struct CanPgn8192 {
	uint8_t gunnum;
	uint16_t opvol;
	uint16_t opcurr;
	uint8_t soc;
	uint8_t battmintemp;
	uint8_t battmaxtemp;
	uint16_t singlebattmaxvol;
	uint16_t singlebattminvol;
	uint8_t devenvtemp;
	uint16_t chaguidevol;
	uint16_t bmsneedvol;
	uint16_t bmsneedcurr;
	uint8_t chamode;
	uint16_t bmschavolcal;
	uint16_t bmschacurrcal;
	uint16_t leftchatime;
	uint8_t chaitftemp1;
	uint8_t chaitftemp2;
	uint8_t chaitftemp3;
	uint8_t chaitftemp4;
};

/*8704遥信帧*/
struct CanPgn8704 {
	uint8_t gunnum;
	
	uint8_t state:2;
	uint8_t allfail:1;
	uint8_t allalarm:1;
	uint8_t e_stop_button:1; /*"急停按钮故障"*/
	uint8_t smoke_fail:1;  /*"烟感故障"*/
	uint8_t ac_circuit_breaker:1;  /*"交流输入断路器故障"*/
	uint8_t dc_bus_contact:1; /*"直流母线输出接触器拒动/误动故障"*/
	
	uint8_t dc_bus_fuse:1; /*"直流母线输出熔断器故障"*/
	uint8_t gun_elec_lock:1;  /*"充电接口电子锁故障"*/
	uint8_t dev_fan:1;      /*"充电桩风扇故障"*/
	uint8_t arrester:1; /*"避雷器故障"*/
	uint8_t insulate_check:1; /*"绝缘监测故障"*/
	uint8_t battery_reverse:1;  /*"电池极性反接故障"*/
	uint8_t charging_vcg:1;      /*"充电中车辆控制导引故障"*/
	uint8_t dev_over_temp:1;   /*"充电桩过温故障"*/
	
	uint8_t gun_over_temp:1;      /*"充电接口过温故障"*/
	uint8_t gun_not_homing:1;    /*"充电枪未归位告警"*/
	uint8_t bms_comm_fail:1;         //"BMS通信故障"*/
	uint8_t vol_in_over:1;       /*"输入电压过压故障"*/
	uint8_t vol_in_low:1;        /*"输入电压欠压故障"*/
	uint8_t dc_bus_vol_over:1;  /*"直流母线输出过压故障"*/
	uint8_t dc_bus_vol_low:1;   /*"直流母线输出欠压故障"*/
	uint8_t dc_bus_curr_over:1;     /*"直流母线输出过流故障"*/
	
	uint8_t mod_fail:1;           /*"充电模块故障"*/
	uint8_t mod_ac_fail:1;       /*"充电模块交流输入故障"*/
	uint8_t mod_ac_vol_over:1;  /*"充电模块交流输入过压故障"*/
	uint8_t mod_ac_vol_low:1; /*"充电模块交流输入欠压故障"*/
    uint8_t mod_ac_lost_phase:1;   /*"充电模块交流输入缺相故障"*/
	uint8_t mod_dc_short:1;  /*"充电模块直流输出短路故障"*/
	uint8_t mod_dc_currt_over:1;  /*"充电模块直流输出过流故障"*/
	uint8_t mod_dc_vol_over:1;   /*"充电模块直流输出过压故障"*/
	
	uint8_t mod_dc_vol_low:1;     /*"充电模块直流输出欠压故障"*/
    uint8_t mod_temp_over:1;     /*"充电模块过温故障"*/
	uint8_t mod_comm_fail:1;        /*"充电模块通信故障" */
	uint8_t mod_fan_fail:1;         /*"充电模块风扇故障"	*/
	uint8_t car_gun_link_state:1;
	uint8_t dev_gun_link_state:1;
	uint8_t gun_lock_state:1;
	uint8_t dc_contact_state:1; /*直流输出接触器状态*/

	uint16_t otherfail;
};

/*8960遥信帧*/
struct CanPgn8960 {
	uint8_t gunnum;
	
	uint8_t dev_door_fail:1; /*"门禁故障"*/
	uint8_t dc_contact_adhesion:1; /*"直流输出接触器粘连故障"*/
	uint8_t insulate_check_fail:1; /*"绝缘检测告警"*/
	uint8_t release_fail:1;  /*"泄放回路故障"*/
	uint8_t dev_temp_over:1; /*"充电桩过温告警"*/
	uint8_t gun_temp_over:1; /*"充电枪过温告警"*/
	uint8_t ac_contact_fail:1; /*"交流输入接触器据动/误动故障"*/
	uint8_t ac_contact_adhesion:1; /*"交流输入接触器粘连故障"*/
	
	uint8_t aux_power_fail:1;  /*"辅助电源故障"*/
	uint8_t shunt_contact_fail:1; /*"并联接触器据动/误动故障"*/
	uint8_t shunt_contact_adhesion:1; /*"并联接触器粘连故障"*/
    
};

/*心跳帧*/
struct CanKeeplive
{
	uint8_t gunnum;
	uint8_t cnt;
	uint8_t recvstate;
	uint8_t charserverstate;
};

/*错误帧*/
struct CanErrorFlame
{
	uint8_t gunnum;
	uint8_t chastartfinishstateover:1;
	uint8_t chastopfinishstateover:1;
	uint8_t yxover:1;
    uint8_t ycover:1;
	uint8_t sendchaparaover:1;
};

#pragma pack() 


enum CAN_ERR{
    CAN_ERR_CHARGE_PARA_ACK_OVER = 0X0002,
    CAN_ERR_START_ACK_OVER=0X0004,
    CAN_ERR_WAIT_START_ACK_OVER=0X0008,
    CAN_ERR_STOP_ACK_OVER=0X0010,
    CAN_ERR_WAIT_STOP_ACK_OVER=0X0020,
    CAN_ERR_TIME_ACK_OVER=0X0040,
    CAN_ERR_CHARGE_SERVER_ACK_OVER=0X0080,

    CAN_ERR_LOCK_ACK_OVER=0X0100,
    CAN_ERR_SET_POWER_ACK_OVER=0X0200,
    CAN_ERR_SET_DEV_ACK_OVER=0X0400,
    CAN_ERR_REMOTE_INFO_ACK_OVER=0X0800,
    CAN_ERR_REMOTE_TEST_ACK_OVER=0X1000,
    
};

typedef void (*can_callback)(uint32_t pgn, uint8_t *msg, uint32_t len);

int32_t can_module_init(can_callback callback);

int32_t can_module_recv(uint32_t gunnum,uint32_t pgn,uint8_t *buf);
void can_module_clear_ack(uint32_t gunnum, uint32_t pgn);

/*启动充电帧*/
void can_start_charging(uint32_t gunnum,uint32_t control);

/*停止充电帧*/
void can_stop_charging(uint32_t gunnum,uint32_t reason);

/*下发对时帧*/
void can_time_sync(uint32_t gunnum, uint16_t year, uint8_t mon, uint8_t date, uint8_t hour, uint8_t min, uint16_t sec);

/*版本校验帧*/
void can_ver_check(uint32_t gunnum,uint32_t ver);

/*下发充电参数信息帧*/
void can_set_charging_para(uint32_t gunnum,const uint8_t *data,int32_t len);

/*充电服务启停帧*/
void can_set_charging_service(uint32_t gunnum,uint32_t cmd);

/*电子锁控制帧*/
void can_set_lock_control(uint32_t gunnum,uint32_t no,uint32_t cmd);

/*功率调节帧*/
void can_set_power(uint32_t gunnum,uint32_t type,uint32_t value);

/*充电桩配置参数查询帧*/
void can_req_dev_config(uint32_t gunnum);

/*充电启动完成帧应答*/
void can_start_charging_finish_ack(uint32_t gunnum,uint32_t control,uint32_t flag);

/*充电停止完成应答*/
void can_stop_charging_finish_ack(uint32_t gunnum,uint32_t flag);

/*8448遥测帧*/
void can_send_8448(uint32_t gunnum,uint32_t totalkwh,uint32_t totaltime);

/*12544遥测帧*/
void can_send_12544(void);

/*心跳帧*/
void can_send_keeplive(uint32_t gunnum,uint8_t state);

/*错误帧*/
void can_send_error(uint32_t gunnum, enum CAN_ERR code);

#endif

